/*
 * DataSimulator.cpp
 *
 *      Author: Jerome RD Soine and Christoph A Brand
 *      Institution: Schwarz goup, Institute for Theoretical Physics, Heidelberg University, Germany
 */

#include "DataSimulator.h"
#include "include/core/utility/VectorOperations.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <fstream>

DataSimulator::DataSimulator(OptimizationObject * o, bool ACMFA){
	srand ( time(NULL) );
	opti_object = o;
	int nr_of_sf = ActiveCableModel::getFiberList(opti_object->get_cell_mesh_file()).size();
	vector<double> tensions(nr_of_sf+1);
	ofstream fout((o->get_project_folder() + "/simulated_fiber_tensions.txt").c_str());
	tensions[0]=0.06;
	fout << tensions[0] << endl;
	for(int i=1; i<=nr_of_sf; i++)
	{
		tensions[i] = ((double)(rand() % 3000))/((double) 1000);
		fout << tensions[i] << endl;
	}
	/*
	fout << "Network: " << tensions[0] << endl;
	for(int i=1; i<=nr_of_sf; i++){
		tensions[i] = rand() % 100;
		fout << "Fiber " << i <<": " << tensions[i] << endl;
	}
	*/
	fout.flush();
	fout.close();

	cout << "Tension vector: ";
	VectorOperations::cout_std_vector(tensions);

	if(ACMFA){
		//Init ForceTransmission shapes from file
		vector<Shape*> shapes = Ellipse::get_shapes_from_file(opti_object->get_shape_file());
		vector<Ellipse*> ellipses(shapes.size());
		for(unsigned int i=0; i<shapes.size(); i++) ellipses[i] = (Ellipse *) shapes[i];
		acm = (ActiveCableModel*) new ActiveCableModel_FA(opti_object->get_cell_mesh_file(),
		    										opti_object->get_project_folder(),
		    										50.0, tensions, ellipses);
	}
	else
		acm = new ActiveCableModel(opti_object->get_cell_mesh_file(),
		    										opti_object->get_project_folder(),
		    										50.0, tensions);
	fem = new FEMCalc(opti_object->get_young_mod(),opti_object->get_poisson_ratio(),opti_object->get_mesh_point1(),
			opti_object->get_mesh_point2(),opti_object->get_degree_of_refinement(),acm->getForceTransmissionShapes());
    acm->run();
    fem->run(acm->get_force_transmissions());
}

DataSimulator::~DataSimulator(){
	delete acm;
	delete fem;
}

void DataSimulator::write_displacement_file(string filename, int nr_of_points){
	srand ( time(NULL) );
	ofstream fout(filename.c_str());
	double x_width = opti_object->get_mesh_point2()[0] - opti_object->get_mesh_point1()[0];
	double x_start = opti_object->get_mesh_point1()[0];
	double y_width = opti_object->get_mesh_point2()[1] - opti_object->get_mesh_point1()[1];
	double y_start = opti_object->get_mesh_point1()[1];

	for(int i=0; i<nr_of_points; i++){
		double x = (double)rand()/RAND_MAX * x_width + x_start;
		double y = (double)rand()/RAND_MAX * y_width + y_start;

		dealii::Point<3> eval_point(x,y,0);
		Vector<double> displacements(3);
		fem->point_evaluation(eval_point, displacements);

		double dx = displacements[0];
		double dy = displacements[1];

		fout << x << "\t" << y << "\t" << dx << "\t" << dy << endl;
	}

	fout.flush();
	fout.close();

	fem->output((filename+".vtk").c_str());

}


